package com.ruoyi.system.service.impl;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.ruoyi.common.enums.AggregationMethod;
import com.ruoyi.common.enums.DataType;
import com.ruoyi.common.enums.TimeGranularity;
import com.ruoyi.system.domain.RpcMsgLog;
import com.ruoyi.system.domain.SysCompanyThingsboard;
import com.ruoyi.system.domain.vo.QueryVo;
import com.ruoyi.system.service.IRpcMsgLogService;
import com.ruoyi.system.service.IThingsBoardTenantService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.thingsboard.rest.client.RestClient;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityIdFactory;
import org.thingsboard.server.common.data.id.RuleChainId;
import org.thingsboard.server.common.data.kv.Aggregation;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.TsKvEntry;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.data.page.SortOrder.Direction;
import org.thingsboard.server.common.data.rule.RuleChain;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

@Slf4j
@Service
public class ThingsBoardTenantServiceImpl implements IThingsBoardTenantService {
    @Value("${tb.url}")
    private String url;

    @Value("${tb.ws}")
    private String ws;

    @Autowired
    private IRpcMsgLogService rpcMsgLogService;

    private RestClient initializeRestClient(SysCompanyThingsboard sysCompanyThingsboard) {
        RestClient restClient = null;
        String tenantUsername = sysCompanyThingsboard.getTbUsername();
        String tenantPassword = sysCompanyThingsboard.getTbPassword();
        restClient = new RestClient(url);
        restClient.login(tenantUsername, tenantPassword);
        if (restClient.getToken() == null) {
            restClient = null;
        }
        return restClient;
    }

    private RestClient getRestClientInstance(SysCompanyThingsboard sysCompanyThingsboard) {
        return initializeRestClient(sysCompanyThingsboard);
    }

    private DeviceProfileId lookupMqttDeviceProfileId(String name, SysCompanyThingsboard sysCompanyThingsboard) {
        DeviceProfileId deviceProfileId = DeviceProfileId.fromString(sysCompanyThingsboard.getTbMqttDeviceProfileId());
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        DeviceProfile deviceProfile = restClient.getDeviceProfileById(deviceProfileId).get();
        restClient.close();
        return deviceProfile.getId();
    }

    private DeviceProfileId lookupHttpDeviceProfileId(String name, SysCompanyThingsboard sysCompanyThingsboard) {
        DeviceProfileId deviceProfileId = DeviceProfileId.fromString(sysCompanyThingsboard.getTbHttpDeviceProfileId());
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        DeviceProfile deviceProfile = restClient.getDeviceProfileById(deviceProfileId).get();
        restClient.close();
        return deviceProfile.getId();
    }

    private DeviceProfileId lookupCoapDeviceProfileId(String name, SysCompanyThingsboard sysCompanyThingsboard) {
        DeviceProfileId deviceProfileId = DeviceProfileId.fromString(sysCompanyThingsboard.getTbCoapDeviceProfileId());
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        DeviceProfile deviceProfile = restClient.getDeviceProfileById(deviceProfileId).get();
        restClient.close();
        return deviceProfile.getId();
    }

    private DeviceProfileId lookupLwm2mDeviceProfileId(String name, SysCompanyThingsboard sysCompanyThingsboard) {
        DeviceProfileId deviceProfileId = DeviceProfileId.fromString(sysCompanyThingsboard.getTbLwm2mDeviceProfileId());
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        DeviceProfile deviceProfile = restClient.getDeviceProfileById(deviceProfileId).get();
        restClient.close();
        return deviceProfile.getId();
    }

    @Override
    public String getWsUrl(SysCompanyThingsboard sysCompanyThingsboard) {
        String url = null;
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        String token = restClient.getToken();
        if (token != null) {
            url = ws + token;
        }
        return url;
    }

    @Override
    public Device saveDefaultDevice(String name, SysCompanyThingsboard sysCompanyThingsboard) {
        Device device = new Device();
        device.setName(name);
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        device = restClient.saveDevice(device);
        restClient.close();
        log.debug("{}", device);
        return device;
    }

    @Override
    public Device saveMqttDevice(String name, SysCompanyThingsboard sysCompanyThingsboard) {
        Device device = new Device();
        device.setName(name);
        device.setDeviceProfileId(lookupMqttDeviceProfileId("MQTT", sysCompanyThingsboard));
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        device = restClient.saveDevice(device);
        restClient.close();
        log.debug("{}", device);
        return device;
    }

    @Override
    public Device saveHttpDevice(String name, SysCompanyThingsboard sysCompanyThingsboard) {
        Device device = new Device();
        device.setName(name);
        device.setDeviceProfileId(lookupHttpDeviceProfileId("HTTP", sysCompanyThingsboard));
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        device = restClient.saveDevice(device);
        restClient.close();
        log.debug("{}", device);
        return device;
    }

    @Override
    public Device saveCoapDevice(String name, SysCompanyThingsboard sysCompanyThingsboard) {
        Device device = new Device();
        device.setName(name);
        device.setDeviceProfileId(lookupCoapDeviceProfileId("CoAP", sysCompanyThingsboard));
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        device = restClient.saveDevice(device);
        restClient.close();
        log.debug("{}", device);
        return device;
    }

    @Override
    public Device saveLwm2mDevice(String name, SysCompanyThingsboard sysCompanyThingsboard) {
        Device device = new Device();
        device.setName(name);
        device.setDeviceProfileId(lookupLwm2mDeviceProfileId("LwM2M", sysCompanyThingsboard));
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        device = restClient.saveDevice(device);
        restClient.close();
        log.debug("{}", device);
        return device;
    }

    @Override
    public void deleteDevice(String id, SysCompanyThingsboard sysCompanyThingsboard) {
        DeviceId deviceId = DeviceId.fromString(id);
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        restClient.deleteDevice(deviceId);
        restClient.close();
    }

    @Override
    public Boolean saveMqttDeviceCredentials(JSONObject fields, SysCompanyThingsboard sysCompanyThingsboard) {
        Boolean done = false;
        String deviceId = fields.getString("deviceId");
        JSONObject credentials = fields.getJSONObject("credentials");
        String credentialsValue = credentials.toJSONString();
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        DeviceCredentials deviceCredentials = restClient.getDeviceCredentialsByDeviceId(DeviceId.fromString(deviceId)).get();
        deviceCredentials.setCredentialsType(DeviceCredentialsType.MQTT_BASIC);
        deviceCredentials.setCredentialsValue(credentialsValue);
        restClient.saveDeviceCredentials(deviceCredentials);
        restClient.close();
        return done;
    }

    @Override
    public Boolean saveHttpDeviceCredentials(JSONObject fields, SysCompanyThingsboard sysCompanyThingsboard) {
        Boolean done = false;
        String deviceId = fields.getString("deviceId");
        JSONObject credentials = fields.getJSONObject("credentials");
        String accessToken = credentials.getString("accessToken");
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        DeviceCredentials deviceCredentials = restClient.getDeviceCredentialsByDeviceId(DeviceId.fromString(deviceId)).get();
        deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN);
        deviceCredentials.setCredentialsId(accessToken);
        restClient.saveDeviceCredentials(deviceCredentials);
        restClient.close();
        return done;
    }

    @Override
    public Boolean saveCoapDeviceCredentials(JSONObject fields, SysCompanyThingsboard sysCompanyThingsboard) {
        Boolean done = false;
        String deviceId = fields.getString("deviceId");
        JSONObject credentials = fields.getJSONObject("credentials");
        String accessToken = credentials.getString("accessToken");
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        DeviceCredentials deviceCredentials = restClient.getDeviceCredentialsByDeviceId(DeviceId.fromString(deviceId)).get();
        deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN);
        deviceCredentials.setCredentialsId(accessToken);
        restClient.saveDeviceCredentials(deviceCredentials);
        restClient.close();
        return done;
    }

    @Override
    public Boolean saveLwm2mDeviceCredentials(JSONObject fields, SysCompanyThingsboard sysCompanyThingsboard) {
        Boolean done = false;
        String deviceId = fields.getString("deviceId");
        JSONObject credentials = fields.getJSONObject("credentials");
        String accessToken = credentials.getString("accessToken");
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        DeviceCredentials deviceCredentials = restClient.getDeviceCredentialsByDeviceId(DeviceId.fromString(deviceId)).get();
        deviceCredentials.setCredentialsType(DeviceCredentialsType.LWM2M_CREDENTIALS);
        deviceCredentials.setCredentialsId(accessToken);
        JSONObject credentialsValue = new JSONObject();
        JSONObject client = new JSONObject();
        client.put("endpoint", accessToken);
        client.put("securityConfigClientMode", "NO_SEC");
        credentialsValue.put("client", client);
        JSONObject bootstrap = new JSONObject();
        JSONObject bootstrapServer = new JSONObject();
        bootstrapServer.put("securityMode", "NO_SEC");
        bootstrap.put("bootstrapServer", bootstrapServer);
        JSONObject lwm2mServer = new JSONObject();
        lwm2mServer.put("securityMode", "NO_SEC");
        bootstrap.put("lwm2mServer", lwm2mServer);
        credentialsValue.put("bootstrap", bootstrap);
        deviceCredentials.setCredentialsValue(credentialsValue.toJSONString());
        restClient.saveDeviceCredentials(deviceCredentials);
        restClient.close();
        return done;
    }

    @Override
    public JSONObject getConnectivity(String tbDeviceId, SysCompanyThingsboard sysCompanyThingsboard) {
        JSONObject connectivity = new JSONObject();
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        EntityId entityId = EntityIdFactory.getByTypeAndId("DEVICE", tbDeviceId);
        List<String> targetKeys = Arrays.asList("active", "inactivityAlarmTime", "lastActivityTime", "lastConnectTime", "lastDisconnectTime");
        List<AttributeKvEntry> attributes = restClient.getAttributeKvEntries(entityId, targetKeys);
        for (AttributeKvEntry attribute : attributes) {
            String key = attribute.getKey();
            if (targetKeys.contains(key)) {
                connectivity.put(key, attribute.getValue());
            }
        }
        restClient.close();
        return connectivity;
    }

    @Override
    public JSONObject getLatestTimeSeries(String tbDeviceId, SysCompanyThingsboard sysCompanyThingsboard) {
        JSONObject timeSeries = new JSONObject();
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        EntityId entityId = EntityIdFactory.getByTypeAndId("DEVICE", tbDeviceId);
        List<TsKvEntry> entries = restClient.getLatestTimeseries(entityId, restClient.getTimeseriesKeys(entityId));
        for (TsKvEntry entry : entries) {
            JSONObject item = new JSONObject();
            item.put("value", entry.getValue());
            item.put("ts", entry.getTs());
            timeSeries.put(entry.getKey(), item);
        }
        restClient.close();
        return timeSeries;
    }

    @Override
    public JSONObject getTimeSeriesMeta(String tbDeviceId, QueryVo queryVo, SysCompanyThingsboard sysCompanyThingsboard) {
        Long start = 0L;
        Long end = new Date().getTime();
        JSONArray identifiers = queryVo.filters.getJSONArray("identifiers");
        List<String> keys = new ArrayList<>();
        Iterator<Object> iterator = identifiers.iterator();
        while (iterator.hasNext()) {
            keys.add(iterator.next().toString());
        }
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        EntityId entityId = EntityIdFactory.getByTypeAndId("DEVICE", tbDeviceId);
        List<TsKvEntry> startItems = restClient.getTimeseries(
                entityId, keys, null, Aggregation.NONE,
                Direction.ASC, start, end, 1, false);
        Long startTs = null;
        if (startItems != null && !startItems.isEmpty()) {
            for (TsKvEntry entry : startItems) {
                if (startTs == null || startTs > entry.getTs()) {
                    startTs = entry.getTs();
                }
            }
        }
        List<TsKvEntry> endItems = restClient.getTimeseries(
                entityId, keys, null, Aggregation.NONE,
                Direction.DESC, start, end, 1, false);
        Long endTs = null;
        if (endItems != null && !endItems.isEmpty()) {
            for (TsKvEntry entry : endItems) {
                if (endTs == null || endTs < entry.getTs()) {
                    endTs = entry.getTs();
                }
            }
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        JSONObject meta = new JSONObject();
        if (startTs != null) {
            meta.put("start", sdf.format(new Date(startTs)));
        } else {
            meta.put("start", null);
        }
        if (endTs != null) {
            meta.put("end", sdf.format(new Date(endTs)));
        } else {
            meta.put("end", null);
        }
        return meta;
    }

    @Override
    public JSONObject getHistoricalTimeSeries(String tbDeviceId, QueryVo queryVo, SysCompanyThingsboard sysCompanyThingsboard) {
        Long start = queryVo.filters.getLong("start");
        Long end = queryVo.filters.getLong("end");
        Integer limit = queryVo.filters.getInteger("limit");
        if (limit == null) {
            limit = 10000;
        }
        JSONArray identifiers = queryVo.filters.getJSONArray("identifiers");
        List<String> keys = new ArrayList<>();
        Iterator<Object> iterator = identifiers.iterator();
        while (iterator.hasNext()) {
            keys.add(iterator.next().toString());
        }
        String aggregation = queryVo.filters.getString("aggregation");
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        EntityId entityId = EntityIdFactory.getByTypeAndId("DEVICE", tbDeviceId);
        List<TsKvEntry> timeSeries = restClient.getTimeseries(
                entityId, keys, TimeGranularity.getSuitable(start, end),
                AggregationMethod.valueOfCode(aggregation).getAggregation(),
                Direction.DESC, start, end, limit, false);
        // log.debug("{}", timeSeries);
        JSONObject indexed = new JSONObject();
        for (TsKvEntry entry : timeSeries) {
            Long ts = entry.getTs();
            String tsString = ts.toString();
            String key = entry.getKey();
            Object value = entry.getValue();
            if (!indexed.containsKey(tsString)) {
                JSONObject values = new JSONObject();
                indexed.put(tsString, values);
            }
            indexed.getJSONObject(tsString).put(key, value);
        }
        restClient.close();
        return indexed;
    }

    @Override
    public JSONObject addTelemetryDelta(String tbDeviceId, JSONObject deltas, SysCompanyThingsboard sysCompanyThingsboard) {
        JSONObject result = null;
        try {
            RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
            restClient.getToken();
            JSONObject latest = getLatestTimeSeries(tbDeviceId, sysCompanyThingsboard);
            Set<String> keys = deltas.keySet();
            ObjectMapper mapper = new ObjectMapper();
            ObjectNode rootNode = mapper.createObjectNode();
            for (String key : keys) {
                JSONObject delta = deltas.getJSONObject(key);
                JSONObject previousOne = latest.getJSONObject(key);
                String valueString = "0";
                if (previousOne != null) {
                    valueString = previousOne.getString("value");
                }
                DataType dataType = (DataType) delta.get("type");
                String newValueString = null;
                if (dataType.equals(DataType.INT32)) {
                    Integer deltaValue = Integer.parseInt(delta.getString("value"));
                    Integer currentValue = Integer.parseInt(valueString);
                    currentValue += deltaValue;
                    newValueString = currentValue.toString();
                } else if (dataType.equals(DataType.INT64)) {
                    Long deltaValue = Long.parseLong(delta.getString("value"));
                    Long currentValue = Long.parseLong(valueString);
                    currentValue += deltaValue;
                    newValueString = currentValue.toString();
                } else if (dataType.equals(DataType.FLOAT)) {
                    Float deltaValue = Float.parseFloat(delta.getString("value"));
                    Float currentValue = Float.parseFloat(valueString);
                    currentValue += deltaValue;
                    newValueString = currentValue.toString();
                } else if (dataType.equals(DataType.DOUBLE)) {
                    Double deltaValue = Double.parseDouble(delta.getString("value"));
                    Double currentValue = Double.parseDouble(valueString);
                    currentValue += deltaValue;
                    newValueString = currentValue.toString();
                }
                if (newValueString != null) {
                    rootNode.put(key, newValueString);
                }
            }
            if (!rootNode.isEmpty()) {
                EntityId entityId = EntityIdFactory.getByTypeAndId("DEVICE", tbDeviceId);
                restClient.saveEntityTelemetry(entityId, "LATEST", rootNode);
            }
            result = JSON.parseObject(rootNode.toString());
        } catch (Exception e) {
            log.info("",e);
            StackTraceElement[] traces = e.getStackTrace();
            for (StackTraceElement trace : traces) {
                log.debug(trace.toString());
            }
        }
        return result;
    }

    @Override
    public String importRuleChainEx(String name, String content, SysCompanyThingsboard sysCompanyThingsboard) {
        RuleChainId ruleChainId = null;
        try {
            JSONObject parsed = JSONObject.parseObject(content);
            JSONArray ruleChains = parsed.getJSONArray("ruleChains");
            JSONObject ruleChain = ruleChains.getJSONObject(0);
            ruleChain.put("name", name);
            RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
            String apiUrl = url + "/api/ruleChains/import";
            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders requestHeaders = new HttpHeaders();
            requestHeaders.setContentType(MediaType.APPLICATION_JSON);
            requestHeaders.set("X-Authorization", "Bearer " + restClient.getToken());
            HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(parsed, requestHeaders);
            restTemplate.postForObject(apiUrl, requestEntity, String.class);
            PageData<RuleChain> ruleChainList = restClient.getRuleChains(new PageLink(10));
            for (RuleChain ruleChainItem : ruleChainList.getData()) {
                if (ruleChainItem.getName().equals(name)) {
                    ruleChainId = ruleChainItem.getId();
                    break;
                }
            }
        } catch (Exception e) {
            log.info("",e);
            StackTraceElement[] traces = e.getStackTrace();
            for (StackTraceElement trace : traces) {
                log.debug(trace.toString());
            }
        }
        return ruleChainId.getId().toString();
    }

    @Override
    public String importDeviceProfileEx(String name, String content, String ruleChainId, SysCompanyThingsboard sysCompanyThingsboard) {
        String deviceProfileId = null;
        try {
            JSONObject parsed = JSONObject.parseObject(content);
            parsed.put("name", name);
            JSONObject defaultRuleChainId = parsed.getJSONObject("defaultRuleChainId");
            defaultRuleChainId.put("id", ruleChainId);
            RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
            String apiUrl = url + "/api/deviceProfile";
            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders requestHeaders = new HttpHeaders();
            requestHeaders.setContentType(MediaType.APPLICATION_JSON);
            requestHeaders.set("X-Authorization", "Bearer " + restClient.getToken());
            HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(parsed, requestHeaders);
            log.info("===:\n " + apiUrl);
            log.info("入参:\n " + JSONUtil.parseObj(requestEntity));

            String response = restTemplate.postForObject(apiUrl, requestEntity, String.class);
            JSONObject saved = JSONObject.parseObject(response);
            deviceProfileId = saved.getJSONObject("id").getString("id");
        } catch (Exception e) {
            log.error("", e);
            log.info("",e);
            StackTraceElement[] traces = e.getStackTrace();
            for (StackTraceElement trace : traces) {
                log.debug(trace.toString());
            }
        }
        return deviceProfileId;
    }

    @Override
    public String sendRpcRequest(String deviceId, JSONObject requestBody, SysCompanyThingsboard sysCompanyThingsboard) {
        String result = null;
        try {
            RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
            String apiUrl = url + "/api/rpc/oneway/" + deviceId;
//            RestTemplate restTemplate = new RestTemplate();
            HttpHeaders requestHeaders = new HttpHeaders();
            requestHeaders.setContentType(MediaType.APPLICATION_JSON);
            requestHeaders.set("X-Authorization", "Bearer " + restClient.getToken());
            HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(requestBody, requestHeaders);
            log.info("apiUrl:{} ,\n X-Authorization:Bearer {},\nsend rpc: {},\n\n",apiUrl,restClient.getToken(),requestBody);
            String response = restClient.getRestTemplate().postForObject(apiUrl, requestEntity, String.class);
            log.info("apiUrl:{} ,\n X-Authorization:Bearer {},\nsend rpc: {},\nresponse:{}"
                    ,apiUrl,restClient.getToken(), requestBody,response);
            result = "success";
        } catch (Exception e) {
            rpcMsgLogService.saveFailureRpcReques(deviceId, requestBody, sysCompanyThingsboard);
            log.info("",e);
            StackTraceElement[] traces = e.getStackTrace();
            for (StackTraceElement trace : traces) {
                log.debug(trace.toString());
            }
            result=e.getMessage();
        }
        return result;
    }

    @Override
    public void exeRpcRequest(RpcMsgLog rpcMsgLog) {
        SysCompanyThingsboard sysCompanyThingsboard = new SysCompanyThingsboard();
        sysCompanyThingsboard.setTbUsername(rpcMsgLog.getTbUsername());
        sysCompanyThingsboard.setTbPassword(rpcMsgLog.getTbPassword());
        RestClient restClient = getRestClientInstance(sysCompanyThingsboard);
        String apiUrl = url + "/api/rpc/oneway/" + rpcMsgLog.getDeviceId();
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.setContentType(MediaType.APPLICATION_JSON);
        requestHeaders.set("X-Authorization", "Bearer " + restClient.getToken());
        HttpEntity<JSONObject> requestEntity = new HttpEntity<JSONObject>(JSONObject.parseObject(rpcMsgLog.getRequestBody()), requestHeaders);
        log.info("exeRpcRequest:rpcMsgLog: {},\n", rpcMsgLog);
        String response = restClient.getRestTemplate().postForObject(apiUrl, requestEntity, String.class);
        log.info("exeRpcRequest  rpcMsgLog {},\n response:{}", rpcMsgLog, response);
    }
}
